(*  :Title:	Supplemental z-Transform Rule Base  *)

(*  :Authors:	Brian Evans, James McClellan  *)

(*
    :Summary:	To define those z-transform operations used only
		in multidimensions.  This reduces the amount of
		memory needed to load in the z-transform.
 *)

(*  :Context:	SignalProcessing`Digital`ZTransform`  *)

(*  :PackageVersion:  2.7	*)

(*
    :Copyright:	Copyright 1989-1991 by Brian L. Evans
		Georgia Tech Research Corporation

	Permission to use, copy, modify, and distribute this software
	and its documentation for any purpose and without fee is
	hereby granted, provided that the above copyright notice
	appear in all copies and that both that copyright notice and
	this permission notice appear in supporting documentation,
	and that the name of the Georgia Tech Research Corporation,
	Georgia Tech, or Georgia Institute of Technology not be used
	in advertising or publicity pertaining to distribution of the
	software without specific, written prior permission.  Georgia
	Tech makes no representations about the suitability of this
	software for any purpose.  It is provided "as is" without
	express or implied warranty.
 *)

(*  :History:	*)

(*  :Keywords:	z-transform, region of convergence	*)

(*
    :Source:	  Dungeon and Mersereau.  {Multidimensional Signal
		Processing}. 1984.
 *)

(*  :Warning:   *)

(*  :Mathematica Version:  1.2 or 2.0  *)

(*  :Limitation:  *)

(*
    :Discussion:  The idea here is to define those z-transform
		  operations which would not be used by undergraduates.
		  They would be loaded by the z-transform rule base
		  when needed.
 *)


(*  :Functions:	  *)



(*  B E G I N     P A C K A G E  *)

BeginPackage[ "SignalProcessing`Digital`MDZTransform`" ]
EndPackage[]

BeginPackage[ "SignalProcessing`Digital`ZTransform`",
	      "SignalProcessing`Digital`ZSupport`",
	      "SignalProcessing`Support`TransSupport`",
	      "SignalProcessing`Support`ROC`",
	      "SignalProcessing`Support`FilterSupport`",
	      "SignalProcessing`Support`SigProc`",
	      "SignalProcessing`Support`LatticeTheory`",
	      "SignalProcessing`Support`SupCode`" ]


If [ TrueQ[ $VersionNumber >= 2.0 ],
     Off[ General::spell ];
     Off[ General::spell1 ] ];


Begin[ "`Private`" ]


downsampleSetUp[ m_, nvars_, f_, n_, z_, s_, nlist_, zlist_, op_ ] :=
        Block [ {mnew, nvarsnew, ztrans, zvarsnew},
		{mnew, nvarsnew, zvarsnew} =
			ReorderResampling[m, nvars, nlist, zlist];
		ztrans = resampleDialogue[ f, mnew, z, nvarsnew, zvarsnew ];
		downsampleZ[ ztrans, zvarsnew, mnew, nvarsnew ] ]

downsampleZ[ztrans_ZTransData, zlist_List, m_?MatrixQ, nlist_List] :=
	Block [	{adj, cosets, downfactor, fz, fztrans,
		 invmtrans, k, rm1, rp1, znew},

		(* generate the kth aliasing term for k = 1 ... Abs[Det[m]] *)
		invmtrans = Inverse[Transpose[m]];
		cosets = DistinctCosetVectors[m];
		term = Exp[-2 Pi I invmtrans . Element[cosets, k]];
		znew = Map[Apply[Times, #]&, Transpose[zlist ^ invmtrans]];

		(* combine the aliasing terms *)
		fztrans = TheFunction[ztrans];
		downfactor = Abs[Det[m]];
		fz = Sum[fztrans /. ReplaceWith[zlist, term znew],
			 {k, 1, downfactor}] / downfactor;

		(* adjust the ROC *)
		(* -- the ROC is defined by Rminus and Rplus which are *)
		(* absolute values so the coset vectors do not affect them *)
		{adj, rm1, rp1} = resampleROC[ztrans, zlist, nlist, invmtrans];

		Transform[adj fz, rm1, rp1] ] /;
	Dimensions[m] == {Length[zlist], Length[nlist]} && ResamplingMatrix[m]

resampleROC[ztrans_, zlist_, nlist_, mat_] :=
	Block [	{adj, dim, i, j, l, rm, rp},

		dim = Length[zlist];
		rm = GetRMinus[ztrans];
		rm = Table[ Apply[ Times, rootROC[ rm, mat[[i]], 1 ] ],
			    {i, 1, dim} ];
		rp = GetRPlus[ztrans];
		rp = Table[ Apply[ Times, rootROC[ rp, mat[[j]], 1 ] ],
			    {j, 1, dim} ];

		adj = Product[ SignalProcessing`ROCinfo[
					nlist[[l]], rm[[l]], rp[[l]] ],
			       {l, 2, dim} ];

		{ adj, rm[[1]], rp[[1]] } ]

resampleDialogue[ f_, mnew_, z_, nvarsnew_, zvarsnew_ ] :=
	Block [	{oldindent, ztrans},
		If [ ! SameQ[ResamplingMatrix[mnew], True],
		     Assuming[ ResamplingMatrix[mnew], dialogueAllFlag ] ];
		If [ dialogueAllFlag,
		     Print[ "( after taking the z-transform of" ];
		     Print[ "  ", f ];
		     Print[ "  with respect to ", nvarsnew, ":" ] ];
		oldindent = indentationString;
		indentationString = "  ";
		ztrans = MultiDTransform[ MakeZObject, ztransform, ZTransformQ,
				   f, nvarsnew, z, zvarsnew, completeOptions ];
		indentationString = oldindent;
		If [ dialogueAllFlag,
		     Print[ "  which finally becomes" ];
		     Print[ "  ", ztrans, " )" ] ];
		indentationString = "";
		ztrans ]

upsampleSetUp[ l_, nvars_, f_, n_, z_, s_, nlist_, zlist_, op_ ] :=
        Block [ {lnew, nvarsnew, ztrans, zvarsnew},
		{lnew, nvarsnew, zvarsnew} =
			ReorderResampling[l, nvars, nlist, zlist];
		ztrans = resampleDialogue[ f, lnew, z, nvarsnew, zvarsnew ];
		upsampleZ[ ztrans, zvarsnew, lnew, nvarsnew ] ]

upsampleZ[ztrans_ZTransData, zlist_List, m_?MatrixQ, nlist_List] :=
	Block [	{adj, fz, rm1, rp1, znew},	        (* [D & M, p. 182] *)
		{adj, rm1, rp1} =
			resampleROC[ ztrans, zlist, nlist, Transpose[m] ];
		znew = Map[Apply[Times, #]&, Transpose[zlist ^ m]];
		fz = TheFunction[ztrans] /. ReplaceWith[zlist, znew];
		Transform[ adj fz, rm1, rp1 ] ] /;
	Dimensions[m] == { Length[zlist], Length[nlist] }


End[]
EndPackage[]


If [ TrueQ[ $VersionNumber >= 2.0 ],
     On[ General::spell ];
     On[ General::spell1 ] ];


(*  E N D I N G     M E S S A G E  *)

Print["Special multidimensional z-transform rules have been loaded."]
Null
